#!/usr/bin/env python
# -*- coding: utf-8 -*-


version="v1.0.5a"
###################################################################################################
#
# logalarm - Сигнализатор поступления текстовой информации
# 
# примеры использования:
#	logalarm 'run.sh $0'
#
###################################################################################################

import sys,os,time,getopt,threading,commands,datetime

def usage():
    line="logalarm "+version+""" Сигнализатор поступления текстовой информации.
При поступлении текстовой информации в фаил или стандартный ввод исполняет указаную программу.
Используйте logalarm [OPTIONS]... EXECUTE [FILE] [...FILE]
Пример: logalarm 'echo $@' mylog.log
 (аналог комманды cat mylog.log)

Управление:
 EXECUTE	             запускат указанный скрипт
 $@,$1,$2		     указание параметров запуска из строк лога
 -h, --help		     показывает эту помощь
 -o, --output=		     указать журнал работы модуля в фаил
 -p, --output-pattern=       указывает шаблон журналирования
 -e, --error-output=	     указывает отдельный журнал для ошибок исполнения (код исполнения >0)
 -r, --error-output-pattern= указывает шаблон журналирования для ошибок исполнения
 -d, --daemon		     запускать в режиме демона.
 -f, --filter=		     обробатывать сообщения содержащие фильтр
 -v, --invert-match	     инвертировать фильтр
 -i, --ignore-case	     игнорировать регистр

Формат шаблонов:
    %(code)s                 код исполнения
    %(log)s		     строка лога
    %(out)s		     обратная информация
    %(commandline)s	     программа    
    %(date)s		     дата и время в формате YYYY-MM-DD HH:MM:SS
"""
    print line

output=sys.stdout
output_pattern="%(date)s CODE:%(code)s LOG:%(log)s OUT:%(out)s\n"
error_output=sys.stderr
error_output_pattern="%(date)s CODE:%(code)s LOG:%(log)s OUT:%(out)s COMANDLINE:%(commandline)s\n"
daemon=False
commandline=""

linefilter=""
linefilterinvert=False
linefilterignorecase=False

class Execute(threading.Thread):
    def __init__(self,commandline,log,output=sys.stdout,output_pattern="%(code)s %(log)s %(out)s",error_output=sys.stderr,error_output_pattern="%(code)s %(log)s %(out)s",daemon=False):
	self.commandline=commandline
	self.log=log
	self.daemon=daemon
	self.output=output
	self.output_pattern=output_pattern
	self.error_output=error_output
	self.error_output_pattern=error_output_pattern
	threading.Thread.__init__(self)
	
    def run(self):
	self.setDaemon(daemon)
	cl=commandline
	try:
	    cl=self.commandline.replace("$@",self.log)
	    logargs = self.log.split(' ')
	    for i in range(len(logargs)):
		cl=cl.replace("$%d" %i , logargs[i])
	    status, result = commands.getstatusoutput(cl)
	    if (status==0):
		self.output.write(self.output_pattern % { "code" : status , "log" : self.log , "commandline" : cl , "out" : result ,"date" : datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S")} )
	    else:
		self.error_output.write(self.error_output_pattern % { "code" : status , "log" : self.log , "commandline" : cl , "out" : result  ,"date" : datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S")} )
	except Exception, ex:
	    status = 500
	    self.error_output.write(self.error_output_pattern % { "code" : status , "log" : self.log , "commandline" : cl , "out" : str(ex).replace("\n"," ") ,"date" : datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S") } )

def execute(line):
    global output
    global output_pattern
    global error_output
    global error_output_pattern
    global daemon
    global commandline
    global linefilterignorecase
    global linefilter
    global linefilterinvert


    tline=line
    if (linefilter!=""):
	if (linefilterignorecase):
	    tline=lower(tline)
	    linefilter=lower(linefilter)
	if (linefilterinvert):
	    if (line.find(linefilter)>-1):
		return 0
	else:
	    if (line.find(linefilter)==-1):
	        return 0
    
    line=line.replace("\n","")
    e=Execute(commandline,line,output,output_pattern,error_output,error_output_pattern)
    
    if (daemon):
        e.start()
    else:
        e.run()


def readfile(args):
    """Метод обработки файлов"""
    for file in [ open(a,'r') for a in args ]:
	for line in file:
	    execute(line)

def readstdin():
    """Метод обработки стандартного ввода"""
    while 1:
	try:
	    line = sys.stdin.readline()
	    if not line: break
	    execute(line)
	except KeyboardInterrupt:	    
	    break
    

def main():

    global output
    global output_pattern
    global error_output
    global error_output_pattern
    global daemon
    global commandline
    global linefilterignorecase
    global linefilter
    global linefilterinvert

    try:
	ops,args = getopt.getopt(sys.argv[1:],"o:p:e:r:hdvf:i",["help","output=","output-pattern=","error-output=","error-output-pattern=","thread","daemon","invert-match","filter=","ignore-case"])
	if len(args)==0:
    	    usage()
	    sys.exit()
    except getopt.GetoptError, err:
	print str(err)
	usage()
	sys.exit()

    for o,a in ops:
	if o in ("-h", "--help"):
	    usage()
	    sys.exit()
	if o in ("-d" , "--daemon"):
	    daemon=1
	if o in ("-o", "--output"):
	    output=open(a,'a')    
	if o in ("-p","--output-pattern"):
	    output_pattern=a+"\n"
	if o in ("-e","--error-output"):
	    error_output=open(a,'a')
	if o in ("-r","--error-output-pattern"):
	    error_output_pattern=a+"\n"
	if o in ("-v","--invert-match"):
	    linefilterinvert=True
	if o in ("-f","--filter"):
	    linefilter=a
	if o in ("-i","--ignore-case"):
	    linefilterignorecase=True
    commandline=args[0]
    if (len(args)>1):
        readfile(args[1:])
    else:
	readstdin()	
    
if (__name__=="__main__"):
    main()
